package com.cqengine.service.Impl;

import com.cqengine.entity.Position;
import com.cqengine.service.PositionService;
import com.googlecode.cqengine.ConcurrentIndexedCollection;
import com.googlecode.cqengine.IndexedCollection;
import com.googlecode.cqengine.index.hash.HashIndex;
import com.googlecode.cqengine.index.unique.UniqueIndex;
import com.googlecode.cqengine.query.Query;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.IteratorUtils;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;

import static com.googlecode.cqengine.query.QueryFactory.and;
import static com.googlecode.cqengine.query.QueryFactory.equal;

@Data
@Slf4j
@Service
public class PositionServiceImpl implements PositionService {


    protected IndexedCollection<Position> posQueue;

    public PositionServiceImpl() {

    }

    public PositionServiceImpl(boolean useIndex) {
        posQueue = new ConcurrentIndexedCollection<>();
        posQueue.addIndex(UniqueIndex.onAttribute(Position.ID));
        posQueue.addIndex(HashIndex.onAttribute(Position.PRICE));
    }


    @Override
    public boolean isContinueRetry(Integer count) {
        if(count < 0){
            return false;
        }
        return true;
    }

    @Override
    public boolean insert(Position position) {
        return posQueue.add(position);
    }

    @Override
    public boolean batchInsert(List<Position> list) {
        return posQueue.addAll(list);
    }

    @Override
    public boolean update(Position position, double price) {
        Position newPosition = position.clone();
        newPosition.setPrice(price);
        return posQueue.update(Arrays.asList(position), Arrays.asList(newPosition));
    }

    @Override
    public boolean update(Position position, boolean trigger) {
        Position newPosition = position.clone();
        newPosition.setIsTriggered(trigger);
        return posQueue.update(Arrays.asList(position), Arrays.asList(newPosition));
    }

    @Override
    public boolean update(Position origin, Position newPosition) {
        return posQueue.update(Arrays.asList(origin), Arrays.asList(newPosition));
    }

    @Override
    public boolean BatchUpdate(List<Position> origin, List<Position> newPosition) {
        return posQueue.update(origin, newPosition);
    }

    @Override
    public boolean delete(Position position){
       return posQueue.remove(position);
    }

    @Override
    public Integer batchDelete(String userId, String symbol) {
        List<Position> queryPositions = query(userId, symbol);
        int count = 0;
        for (Position position : queryPositions) {
            boolean remove = posQueue.remove(position);
            if (remove) {
                count++;
            }
        }
        return count;
    }

    @Override
    public Position query(String id){
        Query<Position> query = null;
        try {
            query = equal(Position.ID, id);
        } catch (ArrayIndexOutOfBoundsException e) {
            log.error("key is error");
        }
        return posQueue.retrieve(query).iterator().next();
    }

    @Override
    public List<Position> query(double price){
        Query<Position> query = equal(Position.PRICE, price);
        return IteratorUtils.toList(posQueue.retrieve(query).iterator());
    }

    @Override
    public List<Position> query(String userId, String symbol) {
        Query<Position> query = and(equal(Position.USERID, userId), equal(Position.SYMBOL, symbol));
        return IteratorUtils.toList(posQueue.retrieve(query).iterator());
    }
}
